﻿using System;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;
using System.Web.Script.Serialization;

namespace KSUNO_EMS
{
    public class ProperJsonResult : JsonResult
    {
        private static readonly Regex DateRegex = new Regex(@"\\/Date\((?<ticks>-?\d+)?\)\\/", RegexOptions.Compiled);
        /// <summary>
        /// If true, date-specific serialization code will be run;
        /// If false, date-specific serialization code will not be run.
        /// </summary>
        public bool HasDates { get; set; }
        /// <summary>
        /// The date format string to be applied. Defaults to "yyyy-MM-dd".
        /// </summary>
        public string DateFormatString { get; set; }

        public ProperJsonResult()
        {
            JsonRequestBehavior = JsonRequestBehavior.AllowGet;
            DateFormatString = "yyyy-MM-dd";
        }

        public override void ExecuteResult(ControllerContext context)
        {
            if (context == null)
                throw new ArgumentNullException("context");

            if (JsonRequestBehavior == JsonRequestBehavior.DenyGet &&
                String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
                throw new InvalidOperationException("JSON Request: Get not allowed!");

            var response = context.HttpContext.Response;
            response.ContentType = !String.IsNullOrEmpty(ContentType)
                                       ? ContentType
                                       : "application/json";

            if (ContentEncoding != null)
                response.ContentEncoding = ContentEncoding;

            if (Data != null)
                response.Write(Serialize());
        }

        /// <summary>
        /// Replaces MS-formatted dates with date strings
        /// </summary>
        /// <param name="match"></param>
        /// <returns></returns>
        public string FixDates(Match match)
        {
            return new DateTime(1970, 1, 1)
                .AddMilliseconds(long.Parse(match.Groups["ticks"].Value))
                .ToString(DateFormatString);
        }

        /// <summary>
        /// Serialize the object to JavaScript and
        /// perform extra formatting on the serialized string as necessary
        /// </summary>
        /// <returns></returns>
        public string Serialize()
        {
            var serializer = new JavaScriptSerializer();
            var serializedData = serializer.Serialize(Data);
            if (HasDates)
                serializedData = DateRegex.Replace(serializedData, FixDates);

            return serializedData;
        }
    }
}
